#ifndef SMC_TBLS_H
#define SMC_TBLS_H
/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/

/*============================================================================*/
/* it's UCODE_START, the table is actually at the start of firmware */
/*============================================================================*/
#define SMC_FW_HDR_START 0x10000

#define SMC_FW_HDR_VER				0x00
#define SMC_FW_HDR_FLGS				0x04
#define SMC_FW_HDR_SW_REGS			0x0c
#define SMC_FW_HDR_STATE_TBL			0x10
#define SMC_FW_HDR_FAN_TBL			0x14
#define SMC_FW_HDR_CAC_CFG_TBL			0x18
#define SMC_FW_HDR_MC_TBL			0x24
#define SMC_FW_HDR_MC_ARB_TBL			0x30
#define SMC_FW_HDR_ENG_PLL_TBL			0x38
#define SMC_FW_HDR_DTE_CFG_TBL			0x40
#define SMC_FW_HDR_PAPM_PARAMS			0x48
/*============================================================================*/


/*----------------------------------------------------------------------------*/
/* offset in smc address space SMC_FW_HDR_STATE_TBL */
/*----------------------------------------------------------------------------*/
struct smc_pp_dpm_to_perf_lvl {
	u8 max_pulse_skip;
	u8 tgt_act;
	u8 max_pulse_skip_step_inc;
	u8 max_pulse_skip_step_dec;
	u8 ps_sampling_time;
	u8 near_tdp_dec;
	u8 above_safe_inc;
	u8 below_safe_inc;
	u8 ps_delta_limit;
	u8 ps_delta_win;
	__be16 pwr_efficiency_ratio;
	u8 rsvd[4];
} __packed;

struct smc_eng_clk {
	__be32 cg_eng_pll_func_ctl_0;
	__be32 cg_eng_pll_func_ctl_1;
	__be32 cg_eng_pll_func_ctl_2;
	__be32 cg_eng_pll_func_ctl_3;
	__be32 cg_eng_pll_ss_0;
	__be32 cg_eng_pll_ss_1;
	__be32 clk;
} __packed;

struct smc_mem_clk {
	__be32 mem_pll_func_ctl_0;
	__be32 mem_pll_func_ctl_1;
	__be32 mem_pll_func_ctl_2;
	__be32 mem_pll_ad_func_ctl;
	__be32 mem_pll_dq_func_ctl;
	__be32 mem_clk_pm_ctl;
	__be32 dll_ctl;
	__be32 mem_pll_ss_0;
	__be32 mem_pll_ss_1;
	__be32 clk;
} __packed;

struct smc_volt {
	__be16 val;
	u8 step_idx;
	u8 phase_settings;
} __packed;

#define SMC_DISP_WATERMARK_LOW	0
#define SMC_DISP_WATERMARK_HIGH	1

#define SMC_STROBE_MODE_RATIO	0x0f
#define SMC_STROBE_MODE_ENA	0x10

#define SMC_MC_FLGS_EDC_RD	BIT(0)
#define SMC_MC_FLGS_EDC_WR	BIT(1)
#define SMC_MC_FLGS_RTT_ENA	BIT(2)
#define SMC_MC_FLGS_STUTTER_ENA	BIT(3)
#define SMC_MC_FLGS_PG_ENA	BIT(4)

#define SMC_STATE_FLGS_AUTO_PULSE_SKIP		BIT(0)
#define SMC_STATE_FLGS_PWR_BOOST		BIT(1)
#define SMC_STATE_FLGS_DEEPSLEEP_THROTTLE	BIT(5)
#define SMC_STATE_FLGS_DEEPSLEEP_BYPASS		BIT(6)

struct smc_lvl {
	u8 mc_reg_set_idx;
	u8 disp_watermark;
	u8 pcie_gen;
	u8 uvd_watermark;
	u8 vce_watermark;
	u8 strobe_mode;
	u8 mc_flgs;
	u8 pad;
	__be32 a_t;
	__be32 b_sp;
	struct smc_eng_clk eng_clk;
	struct smc_mem_clk mem_clk;
	struct smc_volt vddc;
	struct smc_volt mvdd;
	struct smc_volt vddci;
	struct smc_volt std_vddc;
	u8 hysteresis_up;
	u8 hysteresis_down;
	u8 state_flgs;
	u8 mc_arb_set_idx;
	__be32 sq_pwr_throttle_0;
	__be32 sq_pwr_throttle_1;
	__be32 cus_n_max;
	struct smc_volt high_temp_vddc;
	struct smc_volt low_temp_vddc;
	__be32 rsvd[2];
	struct smc_pp_dpm_to_perf_lvl dpm_to_perf_lvl;
} __packed;

#define SMC_SW_STATE_FLGS_DC		BIT(0)
#define SMC_SW_STATE_FLGS_UVD		BIT(1)
#define SMC_SW_STATE_FLGS_VCE		BIT(2)
#define SMC_SW_STATE_FLGS_PCIE_X1	BIT(3)
struct smc_sw_state {
	u8 flgs;
	u8 lvls_n;
	u8 pad2;
	u8 pad3;
} __packed;

#define SMC_DYN_PM_TDP_SAFE_LIMIT_PERCENT 80
struct smc_dyn_pm_params {
	__be32 tdp_limit;
	__be32 near_tdp_limit;
	__be32 safe_pwr_limit;
	__be32 pwrboost_limit;
	__be32 min_limit_delta;
} __packed;

#define SMC_VOLT_MASK_VDDC	0
#define SMC_VOLT_MASK_MVDD	1
#define SMC_VOLT_MASK_VDDCI	2
#define SMC_VOLT_MASKS_N_MAX	4

struct smc_volt_mask_tbl {
	__be32 mask_low[SMC_VOLT_MASKS_N_MAX];
} __packed;

#define SMC_PP_THERMAL_PROTECTION_TYPE_INTERNAL	0x00
#define SMC_PP_THERMAL_PROTECTION_TYPE_EXTERNAL	0x01
#define SMC_PP_THERMAL_PROTECTION_TYPE_NONE	0xff

#define SMC_PP_SYSTEM_FLGS_GPIO_DC			BIT(0)
#define SMC_PP_SYSTEM_FLGS_STEP_VDDC			BIT(1)
#define SMC_PP_SYSTEM_FLGS_GDDR5			BIT(2)
#define SMC_PP_SYSTEM_FLGS_DIS_BABYSTEP			BIT(3)
#define SMC_PP_SYSTEM_FLGS_REGULATOR_HOT		BIT(4)
#define SMC_PP_SYSTEM_FLGS_REGULATOR_HOT_ANALOG		BIT(5)
#define SMC_PP_SYSTEM_FLGS_REGULATOR_HOT_PROG_GPIO	BIT(6)

/* which action to perform when going from ac to dc */
#define SMC_PP_EXTRA_FLGS_DONT_WAIT_FOR_VBLANK		0x08
#define SMC_PP_EXTRA_FLGS_ACTION_MASK			0x07
#define SMC_PP_EXTRA_FLGS_ACTION_GOTO_DPM_LOW_STATE	0x00
#define SMC_PP_EXTRA_FLGS_ACTION_GOTO_INITIAL_STATE	0x01
#define SMC_PP_EXTRA_FLGS_GPIO5_POLARITY_HIGH		0x02

/* a step is a set of volt levels and phase shedding params */
#define SMC_VREG_STEPS_N_MAX 32
#define SMC_SW_STATE_LVLS_N_MAX 16
struct smc_state_tbl {
	u8 thermal_protection_type;
	u8 system_flgs;
	u8 max_vddc_idx;
	u8 extra_flgs;
	__be32	smio_low[SMC_VREG_STEPS_N_MAX];
	struct smc_volt_mask_tbl volt_mask_tbl;
	struct smc_volt_mask_tbl phase_mask_tbl;
	struct smc_dyn_pm_params dyn_pm_params;

	struct smc_sw_state initial;
	struct smc_lvl initial_lvl;

	struct smc_sw_state emergency;
	struct smc_lvl emergency_lvl;

	struct smc_sw_state ulv;
	struct smc_lvl ulv_lvl;

	struct smc_sw_state driver;
	struct smc_lvl driver_lvls[SMC_SW_STATE_LVLS_N_MAX];
} __packed;
/* end of SMC_FW_HDR_STATE_TBL */
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* fan table is not used */
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* offset in smc address space SMC_FW_HDR_CAC_CFG_TBL */
/*----------------------------------------------------------------------------*/
#define SMC_LKGE_LUT_TEMPS_N 16
#define SMC_LKGE_LUT_VOLTS_N 32
#define SMC_LOAD_LINE_SLOPE_SCALE_R 12

struct smc_cac_cfg_tbl {
	__be16 lkge_lut[SMC_LKGE_LUT_TEMPS_N][SMC_LKGE_LUT_VOLTS_N];
	__be32 lkge_lut_v0;
	__be32 lkge_lut_vstep;
	__be32 wnd_time;
	__be32 r_ll;
	__be32 calculation_repeats;
	__be32 l2_num_min_tdp;
	__be32 dc_cac;
	u8 lts_truncate_n;
	u8 shift_n;
	u8 pg_lkge_scale_log2;
	u8 cac_temp;
	__be32 lkge_lut_t0;
	__be32 lkge_lut_tstep;
} __packed;
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* offset in smc address space SMC_FW_HDR_MC_TBL */
/*----------------------------------------------------------------------------*/
#define SMC_MC_REGS_N_MAX 16
#define SMC_MC_REG_SETS_N_MAX 20
struct smc_mc_reg_addr {
	__be16 dw_idx_lp;	/* dword index for low power mode reg set */
	__be16 dw_idx;		/* dword index for standard power reg set */
} __packed;

struct smc_mc_reg_set {
	__be32 vals[SMC_MC_REGS_N_MAX];
} __packed;

struct smc_mc_reg_tbl {
	u8 addrs_n;
	u8 rsvd[3];
	struct smc_mc_reg_addr addrs[SMC_MC_REGS_N_MAX];
	struct smc_mc_reg_set sets[SMC_MC_REG_SETS_N_MAX];
} __packed;
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* offset in smc address space SMC_FW_HDR_MC_ARB_TBL */
/*----------------------------------------------------------------------------*/
struct smc_mc_arb_reg_set {
	__be32 dram_timing_x_0;
	__be32 dram_timing_x_1;
	u8 refresh_rate;
	u8 burst_time;
	u8 pad[2];
} __packed;

#define SMC_MC_ARB_TBL_SETS_N_MAX 16
struct smc_mc_arb_tbl {
	/* this is the *hw* set, not one of the following sets */
	u8 arb_freq_fx_current; /* MAC_MC_CG_ARB_FREQ_Fx */
	u8 rsvd[3];
	struct smc_mc_arb_reg_set sets[SMC_MC_ARB_TBL_SETS_N_MAX];
} __packed;
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* offset in smc address space SMC_FW_HDR_ENG_PLL_TBL */
/*----------------------------------------------------------------------------*/
#define SMC_ENG_PLL_TBL_FREQ_FB_DIV	0x01ffffff
#define SMC_ENG_PLL_TBL_FREQ_P_DIV	0xfe000000
#define SMC_ENG_PLL_TBL_SS_CLK_V	0x000fffff
#define SMC_ENG_PLL_TBL_SS_CLK_S	0xfff00000

#define SMC_ENG_PLL_TBL_STEPS_N 256
#define SMC_ENG_PLL_TBL_STEP_FREQ 512 /* 10 kHz units */
struct smc_eng_pll_tbl {
	__be32 freq[SMC_ENG_PLL_TBL_STEPS_N];
	__be32 ss[SMC_ENG_PLL_TBL_STEPS_N];
} __packed;
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* offset in smc address space SMC_FW_HDR_DTE_CFG_TBL */
/*----------------------------------------------------------------------------*/
#define SMC_DTE_CFG_TBL_FILTER_STAGES_N_MAX 5
#define SMC_DTE_CFG_TBL_MAX_TEMP_DEPENDENT_ENTRIES_N_MAX 16

struct smc_dte_cfg_tbl {
	__be32 tau[SMC_DTE_CFG_TBL_FILTER_STAGES_N_MAX];
	__be32 r[SMC_DTE_CFG_TBL_FILTER_STAGES_N_MAX];
	__be32 k;
	__be32 t0;
	__be32 max_t;
	u8 wnd_sz;
	u8 tdep_cnt;
	u8 temp_select;
	u8 dte_mode;
	u8 t_limits[SMC_DTE_CFG_TBL_MAX_TEMP_DEPENDENT_ENTRIES_N_MAX];
	__be32 tdep_tau[SMC_DTE_CFG_TBL_MAX_TEMP_DEPENDENT_ENTRIES_N_MAX];
	__be32 tdep_r[SMC_DTE_CFG_TBL_MAX_TEMP_DEPENDENT_ENTRIES_N_MAX];
	__be32 t_threshold;
} __packed;
/*----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/* papm table is not used */
/*----------------------------------------------------------------------------*/
#endif
